﻿using System;
using System.Collections.Generic;
using Belmost4PDA.DatabaseWorkPDA;

namespace Belmost4PDA.Fasade
{
    /// <summary>
    /// Структура описания элементов для моста
    /// </summary>
    public class ElementItem
    {
        public string Name; // название
        public int ID; // id записи в BrElem
        public int IDParent; //id родительской записи (-1 соответствует корню или null)
        public int elmCode; //код элемента 
        public int elmClass; // id в таблице связанного классификатора
        public string cName; // название в таблице связанного классификатора
        public ElmBmItem bmItem = null; // для второго прохода и заполнения
        public string NameSuf;
    }
    /// <summary>
    /// Структара для оиания элементов 
    /// </summary>
    public class ElmBmItem
    {
        public string Name; // название
        public int elmCode; //код элемента 
        public int elmOwner; // код родительского
        public string clsName; // имя таблицы классификатора (из одноимнного поля базы)
        public Dictionary<int, string> GetCls()
        {
            if (cls == null)
            {
                // считать данные    
                cls = new Dictionary<int, string>();
                if (clsName != "")
                {
                    QuerySelect q = new QuerySelect();
                    q.Select("Select * from " + clsName);
                    List<DataRows.DataRows> lst = q.GetRows();
                    foreach (DataRows.DataRows rows in lst)
                    {
                        cls[int.Parse(rows.FieldByName(clsName))] = rows.FieldByNameDef("clsText", "");
                    }
                }
            }
            return cls;
        }
        private Dictionary<int, string> cls = null; // список значений классификатора
    }
    /// <summary>
    /// Класс считывающий список элементов для выбранного моста
    /// </summary>
    public class ElementsReader
    {
        public static Dictionary<int, ElmBmItem> ElmBm = new Dictionary<int, ElmBmItem>();
        private static ElementsReader _instance = null;
        /// <summary>
        /// Инициализация при первом обращении
        /// </summary>
        private static void Init()
        {
            if (_instance == null)
            {
                _instance = new ElementsReader();
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ElementsReader"/> class.
        /// Считвает все классификаторы в структуры для хранения.
        /// </summary>
        private ElementsReader()
        {
            //// Считывание даных из elmBm и заполнение ElmBm. ключ - elmCode 
            QuerySelect q = new QuerySelect();
            q.Select("Select elmName, elmCode, ownElm, clsName from elmBM ORDER BY LEN(elmNPP), elmNPP, elmName");
            List<DataRows.DataRows> lst = q.GetRows();
            foreach (DataRows.DataRows rows in lst)
            {
                ElmBmItem it = new ElmBmItem();
                it.Name = rows.FieldByName("elmName");
                it.elmCode = Convert.ToInt32(rows.FieldByName("elmCode"));
                it.elmOwner = Convert.ToInt32(rows.FieldByNameDef("ownElm", "-1"));
                it.clsName = rows.FieldByName("clsName");
                ElmBm.Add(it.elmCode, it);
            }

        }

        /// <summary>
        /// Возвращает список элементов для моста
        /// </summary>
        /// <param name="IdBR">The id BR.</param>
        /// <returns></returns>
        public static List<ElementItem> GetItemForBridge(int IdBR)
        {
            Init();
            /// Алгоритм: запрашивает список из BrElm join ElmBM по elmCode с фильтром IdBr
            /// Считывает и выдает даные
            /// 
            //throw new NotImplementedException();
            List<ElementItem> lst = new List<ElementItem>();
            QuerySelect q = new QuerySelect();
            string sel = "SELECT a.NameSuf, a.idBrElm, a.elmClass, a.ownIdElm, b.elmCode, b.elmName FROM BrElm a INNER JOIN ElmBM b ON a.elmCode = b.elmCode WHERE (a.idBr = '" + IdBR + "') order by LEN(b.ElmNPP), b.ElmNpp, b.ElmCode, LEN(nameSuf), namesuf";
            q.Select(sel);
            List<DataRows.DataRows> list = q.GetRows();
            foreach (DataRows.DataRows rows in list)
            {
                ElementItem it = new ElementItem();
                it.ID = Convert.ToInt32(rows.FieldByName("idBrElm"));
                it.IDParent = Convert.ToInt32(rows.FieldByName("ownIdElm"));
                it.Name = rows.FieldByName("elmName");
                it.NameSuf = rows.FieldByNameDef("nameSuf", "");
                it.elmClass = Convert.ToInt32(rows.FieldByName("elmClass"));
                it.elmCode = Convert.ToInt32(rows.FieldByName("elmCode"));
                if (ElmBm.ContainsKey(it.elmCode))
                    it.bmItem = ElmBm[it.elmCode];
                if (it.bmItem.GetCls().ContainsKey(it.elmClass))
                    it.cName = it.bmItem.GetCls()[it.elmClass];
                else it.cName = "";
                lst.Add(it);
            }
            return lst;
        }

        /// <summary>
        /// Dels the elem.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="idBr"></param>
        public static void DelElem(int id, int idBr)
        {
            // del from brDef
            new QueryExec().Execute(string.Format("delete from brDef where idBrElm = {0}", id));
            // del from brElm
            // read data
            QuerySelect selElm = new QuerySelect();
            selElm.Select(string.Format("select * from brElm where idBrElm = {0}", id));
            string SQL = string.Format("delete from brElm where idBrElm = {0}", id);
            new QueryExec().Execute(SQL);
            MakeLogForElem(idBr, SQL, LogRecord.LogType.BrElmDelete, int.Parse(selElm.GetRows()[0].FieldByNameDef("elmCode", "0")),
                int.Parse(selElm.GetRows()[0].FieldByNameDef("elmClass", "0")),
                           selElm.GetRows()[0].FieldByNameDef("NameSuf", "").Replace("'", "''"), id);
        }
        /// <summary>
        /// Вставка новой записи в BRELM. 
        /// </summary>
        /// <param name="IDBR"></param>
        /// <param name="list"></param>
        /// <returns>Идентификатор вставленной записи</returns>
        /// <param name="id"></param>
        public static int InsertNewElem(int IDBR, ElementItem list, int id)
        {
            int idBrElmNew = (id==-1)?(int.Parse(QueryInsertBuilder.GetNewId("idBrElm"))):(id);
            string ins = "insert into BrElm (idBrElm, idBr, elmcode, elmNum, elmClass, nameSuf, isHave, grdCur, grdmin, grdEff1, grdEff2, minEff1, minEff2, ownIdElm) values({0}, {1}, {2}, 0, {3}, '{4}', 1, 0, 0, 0, 0, 0, 0, {5})";
            QueryExec q = new QueryExec();
            string SQL =
                String.Format(ins, idBrElmNew, IDBR, list.elmCode, list.elmClass, list.NameSuf.Replace("'", "''"),
                              list.IDParent);
            q.Execute(SQL);
            MakeLogForElem(IDBR, SQL, LogRecord.LogType.BrElmInser, list.elmCode, list.elmClass,
                           list.NameSuf.Replace("'", "''"), idBrElmNew);
            return idBrElmNew;
        }

        private static void MakeLogForElem(int idbr, string sql, LogRecord.LogType logType, int elmCode, int elmClass, string suff, int id)
        {
            LogRecord logrecord = new LogRecord();
            LogRecordDetail detItem = new LogRecordDetail();
            logrecord.idBr = idbr;
            logrecord.sqlText = sql;
            logrecord.logType = logType;
            logrecord.tableName = "BrElm";
            logrecord.tableDescr = "Конструктивный элемент";
            logrecord.SetCurrRunDate();
            //
            detItem.fieldName = "elmCode";
            detItem.fieldDescr = "Код элемента";
            detItem.valueNew = elmCode.ToString();
            detItem.valueOld = detItem.valueNew;
            logrecord.detailRecords.Add(detItem);
            detItem = new LogRecordDetail();
            detItem.fieldName = "elmClass";
            detItem.fieldDescr = "Класс элемента";
            detItem.valueNew = elmClass.ToString();
            detItem.valueOld = detItem.valueNew;
            logrecord.detailRecords.Add(detItem);
            detItem = new LogRecordDetail();
            detItem.fieldName = "suff";
            detItem.fieldDescr = "Суффикс";
            detItem.valueNew = suff;
            detItem.valueOld = detItem.valueNew;
            logrecord.detailRecords.Add(detItem);
            detItem = new LogRecordDetail();
            detItem.fieldName = "id";
            detItem.fieldDescr = "id элемента";
            detItem.valueNew = id.ToString();
            detItem.valueOld = detItem.valueNew;
            logrecord.detailRecords.Add(detItem); 
            //
            logrecord.Save();
        }

        /// <summary>
        /// Inserts the new def items.
        /// </summary>
        /// <param name="IDBR"></param>
        /// <param name="item">The item.</param>
        /// <param name="idBrElm"></param>
        public static void InsertNewDefItems(int IDBR, ElementItem item, int idBrElm)
        {
            string sql = "select defbm.defCode, defbm.isDefault from defelmbm join defbm on defelmbm.defCode = defbm.defCode where defelmbm.elmCode={0} and defelmbm.elmClass={1} ";
            QuerySelect q = new QuerySelect();
            q.Select(string.Format(sql, item.elmCode, item.elmClass));
            List<DataRows.DataRows> rows;
            rows = q.GetRows();
            QueryExec qe = new QueryExec();
            foreach (DataRows.DataRows row in rows)
            {
                string s = "insert into BrDef (Idbr,defCode,idBrElm,idBrDef,defScope,defOn,isHave) values({0}, {1}, {2},  {3}, 0, {4},  1)";
                string defcode = row.FieldByName("Defcode");
                string idbrdef = QueryInsertBuilder.GetNewId("idBrDef");
                string isDef = row.FieldByName("isDefault");
                qe.Execute(string.Format(s, IDBR, defcode, idBrElm, idbrdef, isDef));
            }

        }
        ///<summary>
        /// Updates ElmBm, used when treeview is editing
        ///</summary>
        ///<param name="ownIdElm"></param>
        ///<param name="idBr"></param>
        ///<param name="idBrElm"></param>
        public static void UpdateElm(string ownIdElm, string idBr,string idBrElm)
        {
            string sql = "Update BrElm set BrElm.ownIdElm={0} where idBrElm={1}";
            QueryExec q=new QueryExec();
            q.Execute(String.Format(sql, ownIdElm, idBrElm));
        }

    }
}
